home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / net-tools / amitrack / source / amitrackserver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  5.8 KB  |  215 lines

  1. /* AmiTrackServer.c -- a program to keep a running list of available Amigas. */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7.  
  8. #include <exec/types.h>
  9. #include <exec/io.h>
  10. #include <exec/lists.h>
  11. #include <exec/memory.h>
  12.  
  13. #include <clib/exec_protos.h>
  14. #include <clib/alib_protos.h>
  15. #include <clib/dos_protos.h>
  16.  
  17. #include <errno.h>
  18. #include <inetd.h>
  19. #include <sys/types.h>
  20.  
  21. #include <proto/socket.h>
  22. #include <proto/exec.h>
  23. #include <sys/errno.h>
  24. #include <sys/types.h>
  25. #include <sys/socket.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/syslog.h>
  28. #include <netdb.h>
  29.  
  30. #include <pragmas/socket_pragmas.h>
  31. #include <devices/timer.h>
  32.  
  33. #include "AmiTrackShared.h"
  34.  
  35. struct Library * SocketBase = NULL;
  36.  
  37. static ULONG ulPurgeDelay = AMITRACK_TIMEOUT_MINUTES * 60;
  38. static struct TimerStuff  * Timer = NULL;
  39. static struct SocketStuff * TCPStuff = NULL, * UDPStuff = NULL;
  40. static struct ClientList  * clientList = NULL;
  41.  
  42. static void Cleanup(void);
  43. static void HandleClientRequest(struct ClientList *, struct SocketStuff * sSocket);
  44. static void HandleListRequest(struct ClientList *, struct SocketStuff * sSocket);
  45. static void PurgeOldClients(struct ClientList *);
  46.  
  47. int main(int argc, char **argv)
  48. {    
  49.     BOOL BDone = FALSE, BPrintList;
  50.     int nCode, nPort = SERVER_TCP_PORT;
  51.     
  52.     if ((argc == 2)&&(strcmp(argv[1],"?")==0))
  53.     {
  54.         printf("Usage:  AmiTrackServer [Port]\n");
  55.         exit(5);
  56.     }
  57.     atexit(Cleanup);
  58.     
  59.     if (argc >= 2) nPort = atoi(argv[1]);
  60.     nPort = nPort ? nPort : SERVER_TCP_PORT;
  61.     
  62.     UNLESS(SocketBase = OpenLibrary("bsdsocket.library", 2))
  63.         TrackExit("Couldn't open socket.library v2+",RETURN_ERROR);
  64.     UNLESS(Timer = SetupTimer(NULL)) 
  65.         TrackExit("Couldn't setup timer.device.",RETURN_ERROR);
  66.     UNLESS(clientList = SetupClientList(NULL))
  67.         TrackExit("Couldn't create client list.",RETURN_ERROR);
  68.     UNLESS(UDPStuff = SetupSocket(NULL, nPort, SOCK_DGRAM))
  69.         TrackExit("Couldn't setup UDP socket.",RETURN_ERROR);
  70.     UNLESS(TCPStuff = SetupSocket(NULL, nPort, SOCK_STREAM))
  71.         TrackExit("Couldn't setup TCP socket.",RETURN_ERROR);
  72.     listen(TCPStuff->fd,5);
  73.     
  74.     Signal(FindTask(NULL),SIGBREAKF_CTRL_D);
  75.     SetTimer(Timer, ulPurgeDelay, 0);
  76.  
  77.     while(nCode = TrackWait(TCPStuff, UDPStuff, Timer, NULL, NULL))
  78.     {
  79.         BPrintList = FALSE;
  80.  
  81.         if (nCode & CODE_TCP_SOCKET) HandleListRequest(clientList,TCPStuff);
  82.         if (nCode & CODE_UDP_SOCKET) 
  83.         {
  84.             HandleClientRequest(clientList,UDPStuff);
  85.             BPrintList = TRUE;
  86.         }    
  87.         if (nCode & CODE_TIMER_EXPIRED)   
  88.         {
  89.             PurgeOldClients(clientList);     
  90.             SetTimer(Timer, ulPurgeDelay,0);
  91.             BPrintList = TRUE;
  92.         }
  93.         if (nCode & CODE_REFRESH) BPrintList = TRUE;
  94.         
  95.         if (BPrintList) 
  96.         {
  97.             ClearTrackScreen();
  98.             printf("Clients currently logged in to this server (port %i):\n",nPort);
  99.             PrintClientList(clientList);
  100.         }
  101.     }
  102. }
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110. /* Always called when AmiTrack exits, does any necessary cleanup */
  111. void Cleanup(void)
  112. {
  113.     /* Shuts everything down (don't let the calls to Setup*() mislead you) */
  114.     if (Timer)     SetupTimer(Timer);
  115.     if (TCPStuff)     SetupSocket(TCPStuff,0,0);
  116.     if (UDPStuff)     SetupSocket(UDPStuff,0,0);
  117.     if (clientList) SetupClientList(clientList);
  118.     if (SocketBase) CloseLibrary(SocketBase);
  119. }
  120.  
  121.  
  122.  
  123.  
  124. /* Called when someone attempts to connect to us via a TCP stream.
  125.    Dumps the current client list out to the connectee, then closes
  126.    the stream so he knows we're done outputting. */
  127. void HandleListRequest(struct ClientList * ClientList, struct SocketStuff * sSocket)
  128. {
  129.     struct hostent * hp;
  130.     struct sockaddr_in saFrom;
  131.     LONG sSizeOf = sizeof(struct sockaddr_in);
  132.     LONG sNewSocket = accept(sSocket->fd, &saFrom, &sSizeOf);
  133.     struct Client * client = (struct Client *) (ClientList->list.lh_Head);
  134.     
  135.     if (hp = gethostbyaddr((caddr_t)&saFrom.sin_addr, sizeof(saFrom.sin_addr), AF_INET))
  136.     {
  137.         printf("                                                             \r");
  138.         printf("Sending Client list to [%s]...    \r", hp->h_name);
  139.         fflush(stdout);
  140.  
  141.         /* Now send the list */
  142.         while (client->node.ln_Succ)
  143.         {
  144.             send(sNewSocket, client->hostname, strlen(client->hostname)+1, 0L);
  145.             send(sNewSocket, client->comment,  strlen(client->comment) +1, 0L);
  146.             send(sNewSocket, (char *) &client->ulIPAddress, sizeof(ULONG), 0L);
  147.             client = (struct Client *)client->node.ln_Succ;
  148.         }
  149.     }
  150.     else printf("Couldn't determine connection's origin, disconnecting.\n");
  151.     CloseSocket(sNewSocket);
  152. }
  153.  
  154.  
  155. /* Go through the client list, and remove anyone who has a timestamp
  156.    that is older than tCutoff. */
  157. void PurgeOldClients(struct ClientList * ClientList)
  158. {
  159.     time_t tCutOff = time(NULL) - ulPurgeDelay;
  160.     struct Client * client = (struct Client *) ClientList->list.lh_Head;
  161.     struct Client * next;
  162.     
  163.     while (client->node.ln_Succ)
  164.     {
  165.         next = client->node.ln_Succ;
  166.         if (client->tDateStamp < tCutOff) 
  167.         {
  168.             Remove((struct Node *)client); FreeClient(client); ClientList->nListLength--;
  169.         }
  170.         client = next;
  171.     }
  172. }
  173.  
  174.  
  175. /* Called when we are sent a UDP packet by some client */
  176. void HandleClientRequest(struct ClientList * ClientList, struct SocketStuff * sSocket)
  177. {
  178.     char sRecvBuf[1500];
  179.     static struct sockaddr_in saFrom;
  180.     LONG lAddrSize = sizeof(struct sockaddr_in), lReqs;
  181.     struct Client * client;
  182.     struct hostent * hp;
  183.     int nBufLen;
  184.     ULONG ulIPAddress;
  185.     
  186.     if ((nBufLen = recvfrom(sSocket->fd, sRecvBuf, sizeof(sRecvBuf), 0L, &saFrom, &lAddrSize)) < 0) 
  187.     {
  188.         printf("Recvfrom failed.\n");
  189.         return;
  190.     }
  191.     
  192.     hp = gethostbyaddr((caddr_t)&saFrom.sin_addr, sizeof(saFrom.sin_addr), AF_INET);
  193.     UNLESS((hp)&&(hp->h_name))
  194.     {
  195.         printf("Couldn't determine packet's origin.\n");
  196.         return;
  197.     }
  198.     memcpy(&lReqs, sRecvBuf, sizeof(ULONG));
  199.     ulIPAddress = (ULONG) *((ULONG *)hp->h_addr_list[0]);
  200.     UNLESS(client = GetClient(ClientList, ulIPAddress, hp->h_name, 
  201.         (lReqs & REQ_COMMENT) ? PastSpaces(RemoveUnprintableChars(&sRecvBuf[sizeof(ULONG)])) : NULL)) 
  202.     {
  203.         printf("Add/retrieve of client listing failed.\n");
  204.         return;
  205.     }
  206.  
  207.     if (lReqs & REQ_BYE) RemoveClient(ClientList, hp->h_name);
  208.     client->tDateStamp = time(NULL);
  209. }
  210.  
  211.  
  212.  
  213.  
  214.  
  215.